import java.lang.reflect.Method;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import dao.jpa.generico.*;
import dao.anotacoes.*;
import Exception.*;

public aspect InterceptaDAO {
    
    pointcut buscaLista(JPADaoGenerico dao) : call(@MetodoRecuperaLista * *.*(..)) && target(dao);
    pointcut buscaSet(JPADaoGenerico dao): call(@MetodoRecuperaConjunto * *.* (..)) && target(dao);
    pointcut buscaPrimeiro(JPADaoGenerico dao): call(@MetodoRecuperaPrimeiro * *.* (..)) && target(dao);
    pointcut buscaUltimo(JPADaoGenerico dao): call(@MetodoRecuperaUltimo * *.* (..)) && target(dao);
    pointcut busca(JPADaoGenerico dao): call(@MetodoResultadoUnico * *.* (..)) && target(dao);
    
    Object around(JPADaoGenerico dao) 
            throws ObjetoNaoEncontradoException : buscaSet(dao) {
        Signature sig = thisJoinPointStaticPart.getSignature();
        Method metodo = ((MethodSignature)sig).getMethod();
        return dao.buscaConjunto(metodo, thisJoinPoint.getArgs(), metodo.getAnnotation(MetodoRecuperaConjunto.class).namedQuery());
    }
    
    Object around(JPADaoGenerico dao) 
            throws ObjetoNaoEncontradoException : buscaPrimeiro(dao) {
        Signature sig = thisJoinPointStaticPart.getSignature();
        Method metodo = ((MethodSignature)sig).getMethod();
        return dao.buscaUltimoOuPrimeiro(metodo, thisJoinPoint.getArgs(), metodo.getAnnotation(MetodoRecuperaPrimeiro.class).namedQuery());
    }
    
    Object around(JPADaoGenerico dao) 
            throws ObjetoNaoEncontradoException : buscaUltimo(dao) {
        Signature sig = thisJoinPointStaticPart.getSignature();
        Method metodo = ((MethodSignature)sig).getMethod();
        return dao.buscaUltimoOuPrimeiro(metodo,thisJoinPoint.getArgs(), metodo.getAnnotation(MetodoRecuperaUltimo.class).namedQuery());
    }
    
    Object around(JPADaoGenerico dao) throws ObjetoNaoEncontradoException : busca(dao) {
        Signature sig = thisJoinPoint.getSignature();
        Method metodo = ((MethodSignature)sig).getMethod();
        return dao.busca(metodo, thisJoinPoint.getArgs(), metodo.getAnnotation(MetodoResultadoUnico.class).namedQuery());
    }
    
    Object around(JPADaoGenerico dao): buscaLista(dao){
        Signature sig = thisJoinPointStaticPart.getSignature();
        Method metodo = ((MethodSignature)sig).getMethod();
        return dao.buscaLista(metodo, thisJoinPoint.getArgs(), metodo.getAnnotation(MetodoRecuperaLista.class).namedQuery());
    }
    
}
